import React, { useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import history from 'history/browser';
import { useLocalStore } from 'hooks';
import { observer } from 'mobx-react-lite';

import { DirIcon, DownloadIcon } from 'components/icons';
import FileIcon from 'components/icons/FileIcon';
import MultiDropdown, { Option } from 'components/MultiDropdown';
import Text, { TEXT_VIEW } from 'components/Text';
import { classnames, searchCreate } from 'utils';

import RepoContentStore from './RepoContentStore';

import classes from './RepoContent.module.scss';

const cnRepoContent = classnames(classes, 'repoContent');

type RepoContentProps = {
    owner: string;
    repo: string;
};

const RepoContent: React.FC<RepoContentProps> = ({ owner, repo }) => {
    const navigate = useNavigate();
    const { repoDirContent, prevDirUrl, topLevel, repoBranches, setDropdownValue, dropdownValue, breadCrumbs } =
        useLocalStore(() => new RepoContentStore(owner, repo));

    const fetchSubDirHandle = useCallback(
        (url: string) => () => {
            const parseUrl = new URL(url);
            const path = parseUrl.pathname.match(/(?:\/contents)(.*)/)?.[1];
            const ref = new URLSearchParams(parseUrl.search);
            history.replace({
                pathname: window.location.pathname,
                search: searchCreate({ path: path?.length ? path : '/', ref: ref.get('ref') }),
            });
        },
        [],
    );

    const filePreviewHandle = useCallback(
        (url: string) => () => {
            const parseURL = new URL(url);
            navigate((parseURL.pathname.match(/(?:\/repos)(.*)/)?.[1] ?? '') + '/' + parseURL.search, {
                state: 'ok',
            });
        },
        [],
    );

    const getTitle = useCallback((value: Option[]) => value[0].value, []);

    const setDropdownValueHandle = useCallback((value: Option[]) => {
        setDropdownValue(value);

        const search = new URLSearchParams(window.location.href);
        history.replace({
            pathname: window.location.pathname,
            search: searchCreate({ path: search.get('path'), ref: value[0].value }),
        });
    }, []);

    const stopPropagation = useCallback(
        (e: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => e.stopPropagation(),
        [],
    );

    const breadCrumbsHandle = useCallback((src: string) => () => history.push(src), []);
    return (
        <div className={cnRepoContent()}>
            <div className={cnRepoContent('header')}>
                {topLevel ? (
                    <MultiDropdown
                        getTitle={getTitle}
                        value={dropdownValue}
                        onChange={setDropdownValueHandle}
                        singleValue
                        options={repoBranches}
                    />
                ) : (
                    <div className={cnRepoContent('breadCrumbs')}>
                        {breadCrumbs.map((dir, index) => (
                            <Text view={TEXT_VIEW.p18}>
                                <span
                                    onClick={breadCrumbsHandle(dir.src)}
                                    className={cnRepoContent('breadCrumbs-link', {
                                        first: index === 0,
                                        last: index === breadCrumbs.length - 1,
                                    })}
                                >{`${dir.dir}`}</span>
                                {` /`}
                            </Text>
                        ))}
                    </div>
                )}
            </div>
            {!topLevel && (
                <div className={cnRepoContent('content')} onClick={fetchSubDirHandle(prevDirUrl ?? '')}>
                    <DirIcon width={16} height={16} className={cnRepoContent('folder')} />
                    <Text>..</Text>
                </div>
            )}
            {repoDirContent.map((content) => (
                <div
                    key={content.sha + content.name}
                    className={cnRepoContent('content')}
                    onClick={content.type === 'dir' ? fetchSubDirHandle(content.url) : filePreviewHandle(content.url)}
                >
                    {content.type === 'dir' ? (
                        <DirIcon width={16} height={16} className={cnRepoContent('folder')} />
                    ) : (
                        <FileIcon width={16} height={16} color="secondary" />
                    )}
                    <Text className={cnRepoContent('contentName')}>{content.name}</Text>
                    {content.downloadUrl && (
                        <a
                            href={content.downloadUrl}
                            target="_blank"
                            onClick={stopPropagation}
                            download
                            className={cnRepoContent('download')}
                        >
                            <DownloadIcon width={16} height={16} />
                        </a>
                    )}
                </div>
            ))}
        </div>
    );
};

export default observer(RepoContent);
